package com.hy.frame.util;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Stack;

public class ActManager implements com.hy.frame.common.IActivityCache {

    private Application application;
    private Stack<Activity> acts = null;
    private Application.ActivityLifecycleCallbacks callback;

    public void init(Application application) {
        this.application = application;
        if (callback == null) {
            callback = new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
                    add(activity);
                }

                @Override
                public void onActivityStarted(@NonNull Activity activity) {

                }

                @Override
                public void onActivityResumed(@NonNull Activity activity) {

                }

                @Override
                public void onActivityPaused(@NonNull Activity activity) {

                }

                @Override
                public void onActivityStopped(@NonNull Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(@NonNull Activity activity) {
                    remove(activity);
                }
            };
            application.registerActivityLifecycleCallbacks(callback);
        }
    }

    @NonNull
    public Application getApplication() {
        return application;
    }

    /**
     * 添加Activity到容器中
     *
     * @param activity Activity
     */
    @Override
    public void add(Activity activity) {
        if (activity == null) return;
        if (acts == null)
            acts = new Stack<>();
        else {
            //防止重复添加，防止异常不finish
            acts.remove(activity);
        }
        acts.add(activity);
    }


    /**
     * remove activity栈
     *
     * @param activity Activity
     */
    @Override
    public void remove(Activity activity) {
        if (acts == null) return;
        if (activity == null) return;
        if (acts.contains(activity)) {
            acts.remove(activity);
            finish(activity);
        }
    }

    @Override
    public void removeWithClass(Class<?> cls) {
        if (acts == null) return;
        if (cls == null) return;
        //可能有多个实例
        Stack<Activity> rows = new Stack<>();
        for (Activity activity : acts) {
            if (activity.getClass() == cls) {
                rows.add(activity);
                finish(activity);
            }
        }
        if (rows.size() > 0) {
            acts.removeAll(rows);
        }
    }

    /**
     * 清理activity栈
     * finish and remove
     *
     * @param activity 忽略项,可以为空
     */
    @Override
    public void clear(Activity activity) {
        if (actSize() == 0) return;
        while (true) {
            Activity act = curAct();
            if (act == null) break;
            if (activity != null && activity == act) {
                //只移除不销毁
                acts.remove(act);
                continue;
            }
            remove(act);
        }
        //重新加入
        add(activity);
    }

    @Override
    public void clearWithClass(Class<?> cls) {
        if (acts == null) return;
        if (cls == null) return;
        //可能有多个实例
        Stack<Activity> rows = new Stack<>();
        for (Activity activity : acts) {
            if (activity.getClass() == cls) {
                rows.add(activity);
            }
        }
        //清空栈
        clear(null);
        //重新加入
        acts.addAll(rows);
    }

    /**
     * activity栈数量
     */
    @Override
    public int actSize() {
        return acts != null ? acts.size() : 0;
    }

    /**
     * 获取activity
     *
     * @param index 位置
     */
    @Override
    public Activity getAct(int index) {
        if (index >= 0 && acts != null && index < actSize()) {
            return acts.get(index);
        } else return null;
    }

    @Nullable
    @Override
    public Activity curAct() {
        if (actSize() == 0) return null;
        try {
            return acts.lastElement();
        } catch (Exception ignored) {
        }
        return null;
    }

    @Override
    public void finish() {
        Activity act = curAct();
        remove(act);
    }

    private void finish(Activity activity) {
        if (activity.isFinishing() || activity.isDestroyed())
            return;
        activity.finish();
    }

    @Override
    public void exit() {
        LogUtil.d(this.getClass(), "Application exit! ");
        DataManager.getInstance().clear();
        if (application != null && callback != null) {
            application.unregisterActivityLifecycleCallbacks(callback);
        }
        if (acts != null)
            acts.clear();
        acts = null;
        callback = null;
        application = null;
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(0);
    }

    private static class ClassHolder {
        private static final ActManager INSTANCE = new ActManager();
    }

    public static ActManager getInstance() {
        return ActManager.ClassHolder.INSTANCE;
    }
}
